package capricornus.scene.sceneio
{
	import capricornus.actor.Actor;
	import capricornus.actor.events.ActorEvent;
	import capricornus.core.RefreshManager;
	import capricornus.core.StageManager;
	import capricornus.events.RefreshEvent;
	import capricornus.scene.AbstractScene;
	import capricornus.scene.events.ActionSceneEvent;
	
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.display.Sprite;
	import flash.display.Stage;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.MouseEvent;
	import flash.geom.Matrix;
	import flash.geom.Point;

	public class ActionSceneInteractiveController extends EventDispatcher
	{
		private var _hasAddEvent:Boolean = false;
		private var _scene:Sprite;
		private var _stage:Stage;
		
		private var _bitmapData:BitmapData;
		private var _currentOverActor:Actor = null;
		
		/**
		 * 
		 * @param layer 
		 * 
		 */		
		public function ActionSceneInteractiveController( layer:Sprite )
		{
			_scene = layer;
			init();
		}
		
		private function init():void
		{
			_bitmapData = new BitmapData( 1, 1, true, 0 );
			_stage = StageManager.stage;
			
			_scene.addEventListener( MouseEvent.CLICK, onClickLayer, false, 0, true );
			_scene.addEventListener( ActionSceneEvent.ACTION_SCENE_MOUSE_OVER, onSceneMouseOver, false, 0, true );
			_scene.addEventListener( ActionSceneEvent.ACTION_SCENE_MOUSE_OUT, onSceneMouseOut, false, 0, true );
		}
		
		private function onSceneMouseOver( e:ActionSceneEvent ):void
		{
			if( !_hasAddEvent )
			{
				_hasAddEvent = true;
				RefreshManager.instance.addEventListener( RefreshEvent.REFRESH, onRefresh, false, 10000, true );
			}
		}
		
		private function onSceneMouseOut( e:ActionSceneEvent ):void
		{
			if( _hasAddEvent )
			{
				_hasAddEvent = false;
				currentOverActor( null );
				RefreshManager.instance.removeEventListener( RefreshEvent.REFRESH, onRefresh );
			}
		}
		
		private var _index:int = 0;
		private function onRefresh( e:Event ):void
		{
			_index++;
			_index %= 3;
			if( _index != 0 ) return;
			
			var pt:Point = new Point( _stage.mouseX, _stage.mouseY );
			var arrDis:Array = _stage.getObjectsUnderPoint( pt );
			var len:int = arrDis.length;
			
			var actor:Actor = null;
			var lastActor:Actor;
			for( var i:int=len-1; i>=0 && actor==null; i-- )
			{
				var dis:DisplayObject = arrDis[i];
				var p:DisplayObjectContainer = dis.parent;
				while( true )
				{
					if( p==_scene || p==_stage ) 
					{
						break;
					}
					if( p is Actor && lastActor != p && (p as Actor).interactiveEnabled )
					{
						_bitmapData.setPixel32( 0, 0, 0 );
						var ptActor:Point = p.globalToLocal( pt );
						_bitmapData.draw( p, new Matrix(1, 0, 0, 1, -ptActor.x, -ptActor.y) );
						if( (_bitmapData.getPixel32(0, 0) & 0xff000000) != 0 )
						{
							actor = p as Actor;
							break;
						}
						lastActor = p as Actor;
					}
					p = p.parent;
				}
			}
			currentOverActor( actor );
		}
		
		private function currentOverActor( actor:Actor ):void
		{
			if( _currentOverActor != actor )
			{
				if( _currentOverActor != null )
				{
					_currentOverActor.dispatchEvent( new ActorEvent( ActorEvent.ACTOR_MOUSE_OUT ) );
				}
				_currentOverActor = actor;
				if( _currentOverActor != null )
				{
					_currentOverActor.dispatchEvent( new ActorEvent( ActorEvent.ACTOR_MOUSE_OVER ) );
				}
			}
		}
		
		private function onClickLayer( e:MouseEvent ):void
		{
			if( _currentOverActor != null )
			{
				_currentOverActor.dispatchEvent( new ActorEvent( ActorEvent.ACTOR_CLICK ) );
			}
		}
	}
}


















